﻿using Exiled.API.Features;
using Exiled.API.Features.Pools;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace RgCore.Menu
{
    public class HintBuilderSession
    {
        public HintBuilderSession(MenuInterface instance)
        {
            Instance = instance;
        }

        public MenuInterface Instance { get; }
        public List<MenuElement[]> PagedCache { get; private set; } = null;
        public int Pages => _serializedLines.Count;
        private List<string[]> _serializedLines = new List<string[]>();

        public string[] GetString(int page, int pointer, bool left)
        {
            StringBuilder pool = StringBuilderPool.Pool.Get();
            pool.AppendLine($"<align=\"left\">%POS%[>><color=yellow><b>{Instance.CurrentPage.Title}</b></color><<]");
            foreach (string line in _serializedLines[page - 1])
                pool.AppendLine(line);
            pool.AppendLine($"%POS%<b>----------第<color=yellow>{page}</color>/<color=yellow>{_serializedLines.Count}</color>页----------</b>");
            pool.AppendLine
                ($"%POS%<b>{(page > 1 ? "[-] 上一页" : "")}  {(page < _serializedLines.Count ? "[+] 下一页" : "")}  [退格] {(Instance.CurrentPage.Parent == null ? "关闭" : "返回")}</b></align>");
            pool = pool.Replace("%POS%", left ? "" : "<pos=25%>");
            for (int p = 1; p <= Page.MaxChoicesPerPage; p++)
            {
                pool = pool.Replace($"%POINTER{p}_START%", pointer == p ? "<color=yellow><b>></b></color><u>" : "").
                    Replace($"%POINTER{p}_END%", pointer == p ? "</u><color=yellow><b><</b></color>" : "");
            }
            string[] result = pool.ToString().Split('\n');
            StringBuilderPool.Pool.Return(pool);
            return result;
        }

        /// <summary>
        /// 【同步模式】加载页面
        /// </summary>
        public void LoadPage()
        {
            var page = Instance.CurrentPage;
            if (page == null)
                return;
            PagedCache = Instance.CurrentPage.PagedChildren(Instance.Player);
            SerializeString();
        }
        /// <summary>
        /// <para>【异步模式】加载页面，并在完成后自动跳转到该页面</para>
        /// <para>警告：异步模式下，如果页面中包含修改Unity对象的函数，请尽量避免使用异步模式！</para>
        /// </summary>
        public async Task LoadPageAsync()
        {
            if (Instance.CurrentPage == null)
                return;
            await Task.Run(() =>
            {
                var pagedCache = Instance.CurrentPage.PagedChildren(Instance.Player);
                if (Instance.Status.HasFlag(MenuStatus.Busy))
                {
                    PagedCache = pagedCache;
                    SerializeString();
                    Instance.ChangePage(Instance.CurrentPage, true);
                }
            });
        }
        private void SerializeString()
        {
            try
            {
                _serializedLines.Clear();
                foreach (MenuElement[] page in PagedCache)
                {
                    List<string> texts = ListPool<string>.Pool.Get();
                    int choice = 0;
                    foreach (MenuElement me in page)
                    {
                        if (me is FunctionalElement fe)
                        {
                            choice++;
                            string text = $"%POS%%POINTER{choice}_START%%BOLD%<color=%COLOR%>[{choice}] {fe.DisplayText(Instance.Player)}</color> %BOLD_END%%POINTER{choice}_END%";
                            if (fe.Disabled)
                                text = text.Replace("%BOLD%", "").Replace("%BOLD_END%", "").Replace("%COLOR%", "#8A8A8A");
                            else if (!fe.Condition(Instance.Player, out _))
                                text = text.Replace("%BOLD%", "").Replace("%BOLD_END%", "").Replace("%COLOR%", "#FF6A6A");
                            else
                                text = text.Replace("%BOLD%", "<b>").Replace("%BOLD_END%", "</b>").Replace("%COLOR%", "#FFFFFF");
                            texts.Add(text);
                        }
                        else if (me is Text t)
                        {
                            texts.Add($"%POS%{t.Content().Replace('\n', ' ')}");
                        }
                    }
                    _serializedLines.Add(ListPool<string>.Pool.ToArrayReturn(texts));
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
        }
    }
}
